using HotChocolate.Fusion.Events;
using HotChocolate.Fusion.Events.Contracts;
using HotChocolate.Fusion.Extensions;
using static HotChocolate.Fusion.Logging.LogEntryHelper;

namespace HotChocolate.Fusion.SourceSchemaValidationRules;

/// <summary>
/// The <c>@provides</c> directive specifies fields that a resolver provides for the parent type.
/// The <c>fields</c> argument must reference fields that do not have arguments, as fields with
/// arguments introduce variability that is incompatible with the consistent behavior expected of
/// <c>@provides</c>.
/// </summary>
/// <seealso href="https://graphql.github.io/composite-schemas-spec/draft/#sec-Provides-Fields-Has-Arguments">
/// Specification
/// </seealso>
internal sealed class ProvidesFieldsHasArgumentsRule : IEventHandler<OutputFieldEvent>
{
    public void Handle(OutputFieldEvent @event, CompositionContext context)
    {
        var (field, _, schema) = @event;

        if (field.ProvidesInfo is { } providesInfo)
        {
            foreach (var providedField in providesInfo.Fields)
            {
                if (providedField.Arguments.Count != 0)
                {
                    context.Log.Write(
                        ProvidesFieldsHasArguments(
                            providedField,
                            providesInfo.Directive,
                            field,
                            schema));
                }
            }
        }
    }
}
